#include <stdio.h> /*标准输入输出头文件*/
#include <stdlib.h> /*标准库*/
#include <unistd.h> /*一些宏的定义在这里*/
#include <sys/ioctl.h> /*设备的控制*/
#include <sys/types.h> /*定义了一些类型*/
#include <sys/stat.h> /*状态*/
#include <fcntl.h> /*文件控制*/
#include <sys/select.h> /*选择?*/
#include <sys/time.h> /*时间方面的函数*/
#include <errno.h> /*有关错误方面的宏*/

/*主函数入口*/
int main(void)
{
  int i; /*键盘输出时用到的循环变量*/
  int fd; /*buttons设备号*/
  int key_value[4]; /*四个按键的取值*/

  /*打开键盘设备文件*/
  fd = open("/dev/fl2440_key",0); /*以0方式打开*/

  /*打开出错处理*/
  if(fd < 0) /*打开出错就会返回一个负值*/
  {
    perror("open device keys"); /*perror函数?*/
    exit(1); /*返回1*/
  }

  /*for无限循环,等待用户输入*/
  for(;;)
  {
    /*fd_set是types.h中定义的类型,实质上是int型*/
    fd_set rds; /*rds用来存储设备号*/
    int ret; /*for循环内定义的局部变量ret*/

    FD_ZERO(&rds); /*rds初始化*/
    FD_SET(fd,&rds); /*将buttons设备号赋给rds*/

    /*使用系统调用select检查是否能够从/dev/buttons设备读取数据*/
    ret = select(fd + 1,&rds,NULL,NULL,NULL);
    /*返回值ret*/

    /*对ret的处理*/
    if(ret < 0) /*当ret小于0*/
    {
      perror("select");
      exit(1);
    }    

     if(ret == 0) /*当ret等于0*/
    {
      printf("Timeout.\n");
    }else if(FD_ISSET(fd,&rds)) {
      /*读取键盘驱动发出的数据*/
      /*key_value和键盘驱动中定义一致*/

      int ret = read(fd,key_value,sizeof(key_value)); /*注意此处的ret和前面的ret有何不同*/
      /*注意键盘设备读取的特点*/

      /*对ret的处理*/
      if(ret != sizeof(key_value)) /*没有接收够*/
      {
        if(errno != EAGAIN)
          perror("read buttons\n");
        continue;
      }else { /*正确接收,则打印到标准终端*/
        for(i = 0;i < 4;i++) /*最开始定义的循环变量i*/
          printf("K%d %s, key value = 0x%02x\n",i,(key_value[i] & 0x80) ? "released" : key_value[i] ? "pressed down" : "",key_value[i]);
      }
    }
  }

  /*关闭设备*/
  close(fd);
  return 0; /*主函数返回*/
}

